package db_main

import (
	"errors"
	"fmt"
	"longmen/server/pkg/common/helper/util"
	"longmen/server/pkg/db/mysql"
	"longmen/server/pkg/db/mysql/models/models_main"
	pb "longmen/server/pkg/protobuf"
	"strings"

	"gorm.io/gorm"
)

func InsertHongBAO(hongBao *models_main.HongBao, session *gorm.DB) error {
	err := session.Create(hongBao).Error
	if err != nil {
		return fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return nil
}

func QueryById(hongBaoId int32) (hongBao *models_main.HongBao, err error) {
	hongBao = &models_main.HongBao{}
	db := mysql.GetRTable(&models_main.HongBao{})
	res := db.Where("id = ?", hongBaoId).Limit(1).Find(hongBao)
	if errors.Is(res.Error, gorm.ErrRecordNotFound) || res.RowsAffected == 0 {
		err = fmt.Errorf("%s%s", util.Convert2(), "data not found")
	}
	if res.Error != nil {
		err = fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}

	return hongBao, err
}

func UpUserDiamond(userId int64, diamond int, session *gorm.DB) (int64, error) {

	sql := fmt.Sprintf("update db_user set diamond=diamond+? where id=? and diamond+?>=0 ")
	exec := session.Exec(sql, diamond, userId, diamond)
	return exeSQL(sql, exec)
}

func BatchUpdateUserDiamond(session *gorm.DB) (int64, error) {
	sql := fmt.Sprintf("update db_user t1,db_diamond_temp t2 set diamond=diamond+t2.grab_diamond where t1.id=t2.user_id")
	exec := session.Exec(sql)
	return exeSQL(sql, exec)
}

func BatchUpdateHongBao(session *gorm.DB) (int64, error) {
	sql := fmt.Sprintf("update db_hong_bao t1,(select count(1) user_num,sum(grab_diamond) diamond_total,hong_bao_id from db_diamond_temp group by hong_bao_id) t2 " +
		"set t1.send_quantity=send_quantity+t2.user_num,send_diamond=send_diamond+t2.diamond_total, is_done=case when send_quantity=total_quantity then 1 else 0 end" +
		" where id=t2.hong_bao_id and is_done=0")
	exec := session.Exec(sql)
	return exeSQL(sql, exec)
}

/**
 * @Author admin
 * @Description //创建临时表交插入数据
 * @Date 22:59 2022/7/9
 * @Param
 * @return
 **/
func CreateDiamondTemp(session *gorm.DB, diamondList []*models_main.Diamond) (int64, error) {
	sql := "CREATE TEMPORARY TABLE db_diamond_temp (hong_bao_id INT,user_id INT,grab_diamond INT)"
	if err := session.Exec(sql).Error; err != nil {
		return 0, err
	}
	if err := session.Exec(getDiamondVlaus(diamondList)).Error; err != nil {
		return 0, err
	}
	return 1, nil
}

func DropDiamondTemp(session *gorm.DB) error {
	return session.Exec("DROP TEMPORARY TABLE IF EXISTS db_diamond_temp").Error
}

/**
 * @Author admin
 * @Description //TODO
 * @Date 22:58 2022/7/9
 * @Param
 * @return
 **/
func getDiamondVlaus(diamondList []*models_main.Diamond) string {
	valSql := "insert into db_diamond_temp (hong_bao_id,user_id,grab_diamond) values "
	for _, diamond := range diamondList {
		valSql = fmt.Sprintf("%s(%d,%d,%d),", valSql, diamond.HongBaoId, diamond.UserId, diamond.GrabDiamond)
	}
	return strings.TrimRight(valSql, ",")
}

func UpdateBackHongBao(id int, session *gorm.DB) (int64, error) {
	sql := fmt.Sprintf("update db_hong_bao set is_done=1 where is_done=0 and id =?")
	exec := session.Exec(sql, id)
	return exeSQL(sql, exec)
}

func exeSQL(sql string, exec *gorm.DB) (int64, error) {
	if err := exec.Error; err != nil {
		return 0, exec.Error
	}
	return exec.RowsAffected, nil
}

func GetHongBaoList(str string, order string) ([]*pb.HongBaoReq, error) {
	o := make([]*pb.HongBaoReq, 0)
	table := mysql.GetRTable(&models_main.HongBao{})
	err := table.Where(str).Find(&o).Order(order).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("%s%s", util.Convert2(), err.Error())
	}
	return o, err
}
